package us.wili.dev.common.util.qcloud.cos;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.exception.AbstractCosException;
import com.qcloud.cos.meta.OverWrite;
import com.qcloud.cos.request.GetFileLocalRequest;
import com.qcloud.cos.request.MoveFileRequest;
import com.qcloud.cos.request.UpdateFileRequest;
import com.qcloud.cos.request.UploadFileRequest;
import com.qcloud.cos.sign.Credentials;
import com.qcloud.cos.sign.Sign;

/**
 * Created by JasonY on 17/6/7.
 */
public class QcloudCosUtil {

    private QcloudCosProperties properties;

    private Credentials credentials;
    private ClientConfig clientConfig;
    private COSClient cosClient;

    public QcloudCosUtil(QcloudCosProperties properties) {
        this.properties = properties;
        init();
    }

    public QcloudCosUtil(long appId, String secretId, String secretKey, String bucket, Boolean ifPublic, String region) {
        this.properties = new QcloudCosProperties(
            appId, secretId, secretKey, bucket, ifPublic, region
        );
        init();
    }

    private void init() {
        this.credentials = new Credentials(properties.getAppId(), properties.getSecretId(), properties.getSecretKey());
        this.clientConfig = new ClientConfig();
        this.clientConfig.setRegion(properties.getRegion());
        this.cosClient = new COSClient(this.clientConfig, this.credentials);
    }

    public String getPeriodEffectiveSign(String cosPath) throws AbstractCosException {
        long expired = System.currentTimeMillis() / 1000 + properties.getExpireSeconds();
        return Sign.getPeriodEffectiveSign(getBucket(), cosPath, this.credentials, expired);
    }

    public String getOneEffectiveSign(String cosPath) throws AbstractCosException {
        return Sign.getOneEffectiveSign(getBucket(), cosPath, this.credentials);
    }

    public String getDownloadSign(String cosPath) throws AbstractCosException {
        long expired = System.currentTimeMillis() / 1000 + properties.getExpireSeconds();
        return Sign.getDownLoadSign(getBucket(), cosPath, this.credentials, expired);
    }

    public String getDownloadSign(String cosPath, long expiredSeconds) throws AbstractCosException {
        long expired = System.currentTimeMillis() / 1000 + expiredSeconds;
        return Sign.getDownLoadSign(getBucket(), cosPath, this.credentials, expired);
    }


    public String getFileUrl(String cosPath) {
        if (cosPath == null) {
            return null;
        }

        String host = properties.getHost() == null ?
                String.format("http://%s-%s.cos%s.myqcloud.com", properties.getBucket(), properties.getAppId(), properties.getRegion())
                :
                properties.getHost();
        try {
            return properties.getIfPublic() ?
                    host + cosPath
                    :
                    String.format("%s%s?sign=%s", host, cosPath, getDownloadSign(cosPath));
        } catch (AbstractCosException e) {
            return "cos exception";
        }
    }

    public String getFileUrl(String cosPath, long expiredSeconds) {
        String host = properties.getHost() == null ?
                String.format("http://%s-%s.cos%s.myqcloud.com", properties.getBucket(), properties.getAppId(), properties.getRegion())
                :
                properties.getHost();
        try {
            return properties.getIfPublic() ?
                    host + cosPath
                    :
                    String.format("%s%s?sign=%s", host, cosPath, getDownloadSign(cosPath, expiredSeconds));
        } catch (AbstractCosException e) {
            return "cos exception";
        }
    }

    public void move(String fromCosPath, String destCosPath) {
        MoveFileRequest request = new MoveFileRequest(properties.getBucket(), fromCosPath, destCosPath);
        cosClient.moveFile(request);
    }

    public void move(String fromCosPath, String destCosPath, boolean overWrite) {
        MoveFileRequest request = new MoveFileRequest(properties.getBucket(), fromCosPath, destCosPath);
        OverWrite flag = overWrite ? OverWrite.OVER_WRITE : OverWrite.NO_OVER_WRITE;
        request.setOverWrite(flag);
        cosClient.moveFile(request);
    }

    public String download(String cosPath, String localPath) {
        GetFileLocalRequest request = new GetFileLocalRequest(properties.getBucket(), cosPath, localPath);
        request.setUseCDN(false);
        String result = this.cosClient.getFileLocal(request);

        return result;
    }

    public String upload(String cosPath, String localPath) {
        UploadFileRequest uploadFileRequest = new UploadFileRequest(getBucket(), cosPath, localPath);
        return this.cosClient.uploadFile(uploadFileRequest);
    }

    public String upload(UploadFileRequest request) {
        return this.cosClient.uploadFile(request);
    }

    public String update(UpdateFileRequest request) {
        return this.cosClient.updateFile(request);
    }

    public QcloudCosProperties getProperties() {
        return properties;
    }

    public void setProperties(QcloudCosProperties properties) {
        this.properties = properties;
    }

    public String getBucket() {
        return properties.getBucket();
    }

    public long getAppId() {
        return properties.getAppId();
    }

    public String getSecretId() {
        return properties.getSecretId();
    }

    public String getSecretKey() {
        return properties.getSecretKey();
    }

    public boolean getIfPublic() {
        return properties.getIfPublic();
    }

    public String getRegion() {
        return properties.getRegion();
    }

    public long getExpireSecond() {
        return properties.getExpireSeconds();
    }
}
